package ru.averta.notes.other;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

/**
 * <code>UtilsApi</code>
 * <p/>
 * Различный набор функций, необходимых для корректной работы API
 *
 * @author fedor.belov (fedor.belov@mail.ru)
 *         Date: 07.09.11 15:28
 */
public class UtilsApi {

    /**
     * "Вытаскивает" из url'а запроса токен и возвращает его
     *
     * @param request
     * @return
     */
    public static String extractTokenFromRequestUrl(HttpServletRequest request) {
        return request.getParameter("token");
    }

    private static final String API_AUTH_SUCCESS_FIELD = "UtilsApi.authSuccess";

    /**
     * Сохраняет информацию в запросе, что аудентификация прошла успешно
     *
     * @param request
     */
    public static void setSuccessfulAuth(ServletRequest request) {
        request.setAttribute(API_AUTH_SUCCESS_FIELD, true);
    }

    /**
     * Возвращает true, если ранее запрос был помечен успешно прошедшим аудентификацию
     *
     * @param request
     * @return
     */
    public static boolean isSuccessfulAuth(ServletRequest request) {
        return (request.getAttribute(API_AUTH_SUCCESS_FIELD) != null && (Boolean) request.getAttribute(API_AUTH_SUCCESS_FIELD));
    }

    private static final String API_REQUEST_TYPE_FIELD = "UtilsApi.requestType";
    private static final Integer API_REQUEST_TYPE_NOT_API = 0;
    private static final Integer API_REQUEST_TYPE_UNKNOWN = -1;
    private static final Integer API_REQUEST_TYPE_LOGIN = 1;
    private static final Integer API_REQUEST_TYPE_ADD = 2;
    private static final Integer API_REQUEST_TYPE_GET = 3;
    private static final Integer API_REQUEST_TYPE_LOGIN_WITH_SESSION = 4;
    private static final Integer API_REQUEST_TYPE_EDIT = 5;
    private static final Integer API_REQUEST_TYPE_SUGGEST_TAGS_URL = 6;
    private static final Integer API_REQUEST_TYPE_SUGGEST_TAGS = 7;

    /**
     * Возвращается true, если запрос к API, который требует авторизации
     * Возвращает false во всех остальных случаях
     *
     * @param request
     * @return
     */
    public static boolean isRestrictedApiRequest(HttpServletRequest request) {
        Integer requestType = getRequestType(request);

        if (requestType == API_REQUEST_TYPE_NOT_API || requestType == API_REQUEST_TYPE_UNKNOWN) {
            return false;
        } else {
            return true;
        }
    }


    /**
     * Возвращает true, если запрос к API с обязательным парметром "Токен"
     * Возвращает false во всех остальных случаях
     *
     * @param request
     * @return
     */
    public static boolean isApiRequestWithToken(HttpServletRequest request) {
        Integer requestType = getRequestType(request);

        if (requestType == API_REQUEST_TYPE_ADD
                || requestType == API_REQUEST_TYPE_GET
                || requestType == API_REQUEST_TYPE_EDIT
                || requestType == API_REQUEST_TYPE_SUGGEST_TAGS_URL
                || requestType == API_REQUEST_TYPE_SUGGEST_TAGS) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Возвращает true, если запрос к API не требующий сессии
     * Возвращает false во всех остальных случаях (например, запрос не к api)
     *
     * @param request
     * @return
     */
    public static boolean isApiRequestWithoutSession(HttpServletRequest request) {
        Integer requestType = getRequestType(request);

        if (requestType == API_REQUEST_TYPE_NOT_API
                || requestType == API_REQUEST_TYPE_UNKNOWN
                || requestType == API_REQUEST_TYPE_LOGIN_WITH_SESSION) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Возвращает true, если запрос на логин с получением токена
     *
     * @param request
     * @return
     */
    public static boolean isApiTokenLoginRequest(HttpServletRequest request) {
        return (getRequestType(request) == API_REQUEST_TYPE_LOGIN);
    }

    /**
     * Получает из запроса его тип. Если свойство не установлено, вычисляет его и устанавливает
     *
     * @param request
     * @return
     */
    private static Integer getRequestType(HttpServletRequest request) {
        Integer requestType = (Integer) request.getAttribute(API_REQUEST_TYPE_FIELD);

        if (requestType == null) {
            //Свойство не установлено... вычисляем его и устанавливаем

            int startIndex = request.getContextPath().split("/").length;
            String[] path = request.getRequestURI().split("/");
            if (path != null && path.length > startIndex && path[startIndex] != null && path[startIndex].equals("api")) {

                if (path.length-1 < startIndex + 1) {
                    requestType = API_REQUEST_TYPE_UNKNOWN; //http://127.0.0.1:8080/notes/api/
                } else if("login".equals(path[startIndex + 1])) {
                    requestType = API_REQUEST_TYPE_LOGIN;
                } else if ("add".equals(path[startIndex + 1])) {
                    requestType = API_REQUEST_TYPE_ADD;
                } else if ("get".equals(path[startIndex + 1])) {
                    requestType = API_REQUEST_TYPE_GET;
                } else if ("set".equals(path[startIndex + 1])) {
                    requestType = API_REQUEST_TYPE_EDIT;
                } else if ("suggestTagsByUrl".equals(path[startIndex + 1])) {
                    requestType = API_REQUEST_TYPE_SUGGEST_TAGS_URL;
                } else if ("suggestTags".equals(path[startIndex + 1])) {
                    requestType = API_REQUEST_TYPE_SUGGEST_TAGS;
                } else {
                    requestType = API_REQUEST_TYPE_UNKNOWN;
                }

            } else {
                requestType = API_REQUEST_TYPE_NOT_API;
            }

            request.setAttribute(API_REQUEST_TYPE_FIELD, requestType);
        }

        return requestType;
    }

}
